package org.dtrd.modules.doctor.service.impl;

import cn.hutool.core.util.StrUtil;
import com.baomidou.dynamic.datasource.annotation.DS;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.dtrd.common.util.DateUtils;
import org.dtrd.modules.doctor.entity.bean.OutpatientInfo;
import org.dtrd.modules.doctor.entity.bean.OutpatientWeeklyInfo;
import org.dtrd.modules.doctor.entity.po.DtrdEntRdOutpatient;
import org.dtrd.modules.doctor.mapper.DtrdEntRdOutpatientMapper;
import org.dtrd.modules.doctor.service.IDtrdEntRdOutpatientService;
import org.springframework.stereotype.Service;

import java.time.LocalDate;
import java.util.Comparator;
import java.util.Date;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

import static org.dtrd.config.system.Constant.OutpatientStatus;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author QR
 * @since 2021-12-01 14:09:15
 */
@Service
@DS("multi-datasource1")
public class DtrdEntRdOutpatientServiceImpl extends ServiceImpl<DtrdEntRdOutpatientMapper, DtrdEntRdOutpatient> implements IDtrdEntRdOutpatientService {

    @Override
    public OutpatientWeeklyInfo getOutpatientList(Integer doctorId) {
        // 获取当日的时分秒
        Date now = DateUtils.localDate2Date(LocalDate.now());
        List<Date> weekDate = DateUtils.getWeekDate(now);
        // 根据范围查询数据
        Date startOfWeek = weekDate.get(0);
        Date endOfWeek = weekDate.get(6);
        LambdaQueryWrapper<DtrdEntRdOutpatient> outpatientQueryWrapper = Wrappers.lambdaQuery(DtrdEntRdOutpatient.class)
                .eq(DtrdEntRdOutpatient::getDoctorId, doctorId)
                .ge(DtrdEntRdOutpatient::getOutpatientDate, startOfWeek)
                .le(DtrdEntRdOutpatient::getOutpatientDate, endOfWeek);
        List<DtrdEntRdOutpatient> poList = this.list(outpatientQueryWrapper);
        // 补齐 7 天的数据
        List<Date> recordDates = poList.stream()
                .map(DtrdEntRdOutpatient::getOutpatientDate)
                .collect(Collectors.toList());
        List<Date> noRecordDates = weekDate.stream()
                .filter(date -> !recordDates.contains(date))
                .collect(Collectors.toList());
        for (Date date : noRecordDates) {
            poList.add(new DtrdEntRdOutpatient(date, doctorId));
        }
        // 设置展示数据列表
        List<OutpatientInfo> dtoList = poList.stream()
                .map(po -> new OutpatientInfo().parseFromPo(po))
                .sorted(Comparator.comparing(OutpatientInfo::getOutpatientDate))
                .collect(Collectors.toList());
        // 设置返回对象数据将
        OutpatientWeeklyInfo outpatientWeeklyInfo = new OutpatientWeeklyInfo();
        outpatientWeeklyInfo.setDoctorId(doctorId);
        outpatientWeeklyInfo.setServiceContent(this.getServiceContentLatest(doctorId));
        outpatientWeeklyInfo.setOutpatientInfos(dtoList);
        return outpatientWeeklyInfo;
    }

    @Override
    public String getServiceContentLatest(Integer doctorId) {
        LambdaQueryWrapper<DtrdEntRdOutpatient> queryWrapper = Wrappers.lambdaQuery(DtrdEntRdOutpatient.class)
                .eq(DtrdEntRdOutpatient::getDoctorId, doctorId)
                .isNotNull(DtrdEntRdOutpatient::getServiceContent)
                .orderByDesc(DtrdEntRdOutpatient::getCreateTime)
                .select(DtrdEntRdOutpatient::getServiceContent)
                .last("limit 1");
        DtrdEntRdOutpatient query = this.getOne(queryWrapper);
        return Optional.ofNullable(query)
                .map(DtrdEntRdOutpatient::getServiceContent)
                .orElse(null);
    }


    @Override
    public boolean saveOrUpdateOutpatientStatus(OutpatientWeeklyInfo info) {
        List<OutpatientInfo> outpatientInfos = info.getOutpatientInfos();
        outpatientInfos.forEach(outpatientInfo -> {
            DtrdEntRdOutpatient po = new DtrdEntRdOutpatient().parseFromDto(outpatientInfo);
            LambdaUpdateWrapper<DtrdEntRdOutpatient> updateWrapper = basicUpdateWrapper(outpatientInfo.getDoctorId(), outpatientInfo.getOutpatientDate());
            this.saveOrUpdate(po, updateWrapper);
        });
        // 保存服务内容
        if (StrUtil.isNotBlank(info.getServiceContent())) {
            this.saveOrUpdateServiceContent(info.getDoctorId(), info.getServiceContent());
        }
        return true;
    }

    @Override
    public boolean saveOrUpdateServiceContent(Integer doctorId, String serviceContent) {
        LambdaQueryWrapper<DtrdEntRdOutpatient> queryWrapper = Wrappers.lambdaQuery(DtrdEntRdOutpatient.class)
                .eq(DtrdEntRdOutpatient::getDoctorId, doctorId)
                .orderByDesc(DtrdEntRdOutpatient::getCreateTime)
                .last("limit 1");
        DtrdEntRdOutpatient record = this.getOne(queryWrapper);
        record.setServiceContent(serviceContent);
        return updateById(record);
    }

    public LambdaUpdateWrapper<DtrdEntRdOutpatient> basicUpdateWrapper(Integer doctor, String date){
        return Wrappers.lambdaUpdate(DtrdEntRdOutpatient.class)
                .eq(DtrdEntRdOutpatient::getDoctorId, doctor)
                .eq(DtrdEntRdOutpatient::getOutpatientDate, date);
    }

    private static int changeStatus(int status){
        OutpatientStatus outpatientStatus = OutpatientStatus.valueOf(status);
        assert outpatientStatus != null;
        switch (outpatientStatus){
            case UNABLE:
                return OutpatientStatus.ABLE.getStatus();
            case ABLE:
                return OutpatientStatus.UNABLE.getStatus();
            default:
                return 0;
        }
    }
}
